<?php

/**
 * 普洛cc直邮 SDK
 * @author chenyun
 */

namespace App\Service\VendorClient\Shoppuluo;
use App\Model\PssModel\ServiceConfig;
use App\Service\Code\Normal;
use App\Service\AppService\SystemCacheConfigService;
use App\Service\TaskServer\TaskWorker;
use Service\AppService\IdService;

class ShoppuluoApiClient
{
    private $account  = 'Shoppuluo';
    protected $config;
    protected $RouteMap = [
        'createOrder'   => 'wtdex.trade.order.add',
        'uploadPsimage' => 'wtdex.clearance.psimage.add',
        'orderExpress'  => 'wtdex.trade.express.get',
    ];
    /**
     * 初始参数
     * @param obj $collection
     */
    public function __construct( $apiBody = [] ) 
    {
        $this->config = $apiBody;
    }
    
    /**
     * 创建订单
     */
    public function createOrder( $params = [] ) 
    {   
        ini_set('serialize_precision', 16);
        
        if( empty($params['supplierOrder']) || empty($params['orderGoods']) || empty($params['order']) || empty($params['binfo']) ) {
            return Normal::returnCode(Normal::FAIL,"except param supplierOrder or orderGoods or order or binfo");
        }
        //组装订单参数
        $orderInfo = $params['supplierOrder'];
        $order     = $params['order'];
        $binfo     = $params['binfo'];
        //运费
        $deliver_money  = $orderInfo['deliver_money'];
        //商品下单组
        $orderItems = [];
        $productAmt     = $TaxAmt = 0 ;
        foreach ($params['orderGoods'] as $key => $item ) 
        {
            //卖价
            $price              = $item['price'];
            //商品购买规格数量
            $spec_num           = $item['spec_num'];
            //商品购买数量(下单数量 X 起售数量)
            $quantity           = $item['quantity'];
            //实际购买数量
            $buyAcount          = $spec_num * $quantity ;
            //如果商品除不尽，得多取以为，减去实际金额为折扣，折扣不能为负数
            if( $key == 0 ) {
                $singleDeliveryMoney = bcdiv((string)$deliver_money,(string)$quantity,3);
                $singleDeliveryMoney = bcmul((string)$singleDeliveryMoney,(string)100,1);
                $singleDeliveryMoney = bcdiv((string)ceil($singleDeliveryMoney), (string)100,2);
                $price               = bcadd((string)$price, (string)$singleDeliveryMoney,2);
            }
            //单个商品价格
            $singleGoodsPrice   = bcdiv((string)$price, (string)$spec_num,3);
            $singleGoodsPrice   = ceil(bcmul((string)$singleGoodsPrice,(string)'100',1));
            $singleGoodsPrice   = bcdiv((string)$singleGoodsPrice,'100',2);
            $totalGoods         = bcmul((string)$singleGoodsPrice,(string)$buyAcount,2);

            //含税税率
            $tax_rate           = bcadd('1', (string)$item['tax_rate'],4);
            
            //不含税价格
            $not_tax_price      = bcdiv((string)$singleGoodsPrice, (string)$tax_rate,3);
            // echo "含税税率:".$tax_rate."不含税价格：".$not_tax_price;
            $not_tax_price      = ceil(bcmul((string)$not_tax_price,(string)'100',1));
            // echo "含税税率:".$tax_rate."不含税价格：".$not_tax_price;
            $not_tax_price      = bcdiv((string)$not_tax_price,'100',2);
            
            //税金
            $singleGoodsTax     = bcsub((string)$singleGoodsPrice, (string)$not_tax_price,3);
            
            //单个商品总税金
            $totalGoodsTax  = bcmul((string)$singleGoodsTax,(string)$buyAcount,2);
            
            //单个商品总含税价格
            $totalGoods     = bcmul((string)$not_tax_price,(string)$buyAcount,2);
            
            //商品组
            $orderItems[] = [
                "productId"     => $item['supplier_skucode'],
                "productName"   => $item['goods_name'],
                "qty"           => $buyAcount,
                "price"         => $not_tax_price,
                "total"         => $totalGoods,
            ];
            $productAmt = bcadd((string)$productAmt,(string)$totalGoods,2);
            $TaxAmt = bcadd((string)$TaxAmt,(string)$totalGoodsTax,2);
        }
        

        //实际下单金额 
        $real_total_money = $orderInfo['real_total_money'];
        //订单总金额 = 不含税商品总金额 + 总税费 + 运费 - 优惠金额
        $ActualPaidAmt  = bcadd((string)$productAmt,(string)$TaxAmt,2);
        $ActualPaidAmt  = bcadd((string)$ActualPaidAmt,(string)$deliver_money,2);
        //优惠金额
        $discount_money = bcsub((string)$ActualPaidAmt,$real_total_money,2);
        
        //下单支付的时候支付信息
        $apply_extends  = @json_decode($orderInfo['apply_extends'],true);
        
        $payTime        = empty($order['payTime']) ? $orderInfo['pay_time'] :$order['payTime'];
        //支付时间
        $pay_time       = $payTime ? $payTime : time();
        $pay_time       = date('Y-m-d H:i:s',$payTime);     

        //支付流水号
        $pay_sn         = $order['paySerial'] ?? $orderInfo['pay_sn'];
        
        //获取系统配置地址
        $notifyInfo = SystemCacheConfigService::instance()->getCacheInfoBySystemCode('sysconfig');
        if( empty($notifyInfo['NotifyUrl']) ) {
            return Normal::returnCode(Normal::FAIL,"系统回调地址域名NotifyUrl不能为空");
        }
        
        //获取上游供应商支付方式路由
        $payCommanyCode = $apply_extends['payCommanyCode'] ?? '';
        $PayCompanyCode = $order['payCommanyCode'] ? $order['payCommanyCode'] : $payCommanyCode;
        $pay_value      = ServiceConfig::instance()->getConfigByEventsValue($this->account, ServiceConfig::TYPE_PAY, $PayCompanyCode);
        if (empty($pay_value)) {
            return Normal::returnCode(Normal::FAIL, "支付公司编码：【{$PayCompanyCode}】未映射，请联系管理员处理");
        } 
        
        //电商平台信息
        $enterpriseNum = $apply_extends['enterpriseNum'] ?? '';
        $enterpriseName = $apply_extends['enterpriseName'] ?? '';
        $enterpriseNum = $order['enterpriseNum'] ? $order['enterpriseNum'] : $enterpriseNum;
        $enterpriseName = $order['enterpriseName'] ? $order['enterpriseName'] : $enterpriseName;
        //获取身份证正反面
        $IdCardFrontImage = $apply_extends['idCardFrontImage'] ?? '';
        $IdCardBackImage  = $apply_extends['idCardBackImage'] ?? '';
        $IdCardFrontImage = $order['idCardFrontImage'] ? $order['idCardFrontImage'] : $IdCardFrontImage;
        $IdCardBackImage  = $order['idCardBackImage'] ? $order['idCardBackImage'] : $IdCardBackImage;
        
        if (empty($IdCardFrontImage) || empty($IdCardBackImage)) {
            return Normal::returnCode(Normal::FAIL, "身份证图片正反面都需要提供！");
        }
            
        //创建订单数据
        $data = [
            'orderId'                => $orderInfo['supplier_dsn'],
            'orderDate'              => date("Y-m-d H:i:s",time()),
            'name'                   => $orderInfo['receive_name'],
            'province'               => $orderInfo['province'],
            'city'                   => $orderInfo['city'],
            'area'                   => $orderInfo['district'],
            'addr'                   => $orderInfo['receive_address'],
            'zipCode'                => "",
            'cardType'               => 0,
            'cardNo'                 => $orderInfo['buyer_idcard'],
            'consumerName'           => $orderInfo['buyer_realname'],
            'consumerPhone'          => $orderInfo['buyer_phone'],
            'consumerProvince'       => "",
            'consumerCity'           => "",
            'consumerArea'           => "",
            'consumerAddr'           => "",
            'phone'                  => $orderInfo['recveive_phone'],
            'mobile'                 => $orderInfo['recveive_phone'],
            'invoiceHead'            => "",
            'invoiceType'            => "",
            'invoice'                => "",
            'total'                  => (float)$totalGoods,
            'freight'                => (float)$deliver_money,
            'insuredFee'             => 0.00,
            'tax'                    => (float)$TaxAmt,
            'seller'                 => "",
            'notes'                  => "",
            'portCode'               => $this->config["portCode"],
            'ieFlag'                 => "I",
            'busiMode'               => $this->config["busiMode"],
            'pickMode'               => $this->config["pickMode"],
            'stockupFlag'            => $this->config["stockupFlag"],
            'whCode'                 => $this->config["whCode"],
            'expressCode'            => $this->config["expressCode"],
            'expressNo'              => "",
            'destCity'               => "",
            'prodFlag'               => "",
            'senderContact'          => $this->config["senderContact"],
            'senderPhone'            => $this->config["senderPhone"],
            'regno'                  => "",
            'regpno'                 => $enterpriseNum ?? "",
            'paymentCode'            => $pay_value,
            'isgac'                  => 1,
            'isactorder'             => $this->config["isactorder"],
            'isactlogistics'         => $this->config["isactlogistics"],
            'isactpay'               => "",
            'paymethod'              => "",
            'payid'                  => $pay_sn,
            'payaccount'             => $real_total_money,
            'paytime'                => $pay_time,
            'noncashpartamount'      => $discount_money,
            'customerregisterno'     => $orderInfo["buyer_phone"],
            'sellerNick'             => "",
            'shopNick'               => "",
            'payNo'                  => "",
            'overseaRoute3PL'        => "",
            'cusclearanceRoute3PL'   => "",
            'logisticsRoute3PL'      => "",
            'isrecord'               => "",
            'orderItemList'          => [
                "orderItems"  => $orderItems
            ],
            'isPayment'              => "",
            'platformwhere'          => "",
            'storename'              => $this->config["storename"],
            'merdata11'              => "",
            'extrainfoList'          => [],
            'merdata12'              => ""
        ];
        $requestParam = [
            'method'    => 'createOrder',
            'data'      => $data
        ];
        $result = $this->execute($requestParam);
        //上传订单失败或者业务是非cc直邮模式，直接返回
        if($result["code"] != Normal::SUC){
            return $result;
        }  
        return  $this->uploadPsimage($orderInfo['supplier_dsn'],$IdCardFrontImage,$IdCardBackImage);
    }
   

    /**
     * 上传身份证正反面
     */
    public function uploadPsimage( string $orderid,string $IdCardFrontImage,string $IdCardBackImage)
    {
        //上传身份证正面
        $data1 = [
            "fileName"          => $orderid."-1",
            "fileTransferType"  => 1,
            "file"              => $IdCardFrontImage,
            "orderid"           => $orderid,
        ];
        $requestParam = [
            'method'    => 'uploadPsimage',
            'data'      => $data1
        ];
        $res1 = $this->execute($requestParam);
        if($res1["code"] != Normal::SUC){
            return $res1;
        }
        //上传身份证反面
        $data2 = [
            "fileName"          => $orderid."-2",
            "fileTransferType"  => 1,
            "file"              => $IdCardBackImage,
            "orderid"           => $orderid,
        ];
        $requestParam = [
            'method'    => 'uploadPsimage',
            'data'      => $data2
        ];
        $res2 = $this->execute($requestParam);
        if($res2["code"] != Normal::SUC){
            return $res2;
        }
        return Normal::returnCode(Normal::SUC,"订单推送成功");
    }
    /**
     * 查询物流信息
     */
    public function orderExpress( $params = [] )
    {
        //组装订单参数
        $data = [
            'orderId' => $params['supplier_dsn'],
        ];
        $requestParam = [
            'method'    => 'orderExpress',
            'data'      => $data
        ];
        return $this->execute($requestParam);
    }
    /**
     * 加签
     * @param array $param
     */
    protected function getSign( array $param = [] )
    {
        //第一步：按照如下顺序拼成字符串secret+appkey+format+ method + params+ timestamp + token+ v + secret
        $string=$this->config["secret"].$param["appkey"].$param["format"].$param["method"].$param["params"].$param["timestamp"].$this->config["token"].$param["v"].$this->config["secret"];
        //第二步：md5加密
        $string = md5($string);
        //第三步：Base64加密
        $string=base64_encode($string);
        return $string;
    }
    
    /**
     * CURL请求
     * @param $params
     * @return mixed
     */
    public function execute( $param = [] )  
    {
        if( empty($param['data']) ) {
            return Normal::returnCode(Normal::FAIL,"数据不能为空");
        }

        $data   =[];
        $url    = $this->config['baseurl'];
        $method = $param['method'];
        $data["method"]     = $this->RouteMap[$method];
        $data["appkey"]     = $this->config["appkey"];
        $data["token"]      = $this->config["token"];
        $data["format"]     = "json";
        $data["timestamp"]  = date("Y-m-d H:i:s",time());
        $data["v"]          = "1.0";
        $data["params"]     = json_encode($param['data']);
        $data["sign"]       = $this->getSign($data);
        $parameter = [
            [
                'tag'       => $this->account.'_'.$method,
                'uid'       => IdService::instance()->getOtherID(),
                'url'       => $url,
                'data'      => $data,
                'method'    => 'post',
                'format'    => 'x-www-form-urlencoded',
                'header'     => [
                    "Accept-charset: utf-8",
                    "Content-type: application/x-www-form-urlencoded"
                ],
        
            ],
        ];
        $resTask = TaskWorker::instance()->addTask($parameter);
        $resTask = current($resTask);
        $res     = $resTask['response']['result'];
        $resHttp = json_decode($res,true);
        if( isset($resHttp['response']) && $resHttp['response']["code"] == 1 ) {
            return Normal::returnCode(Normal::SUC,"请求成功",$resHttp);
        }
        $message = isset($resHttp['response']) ? json_encode($resHttp,JSON_UNESCAPED_UNICODE) : '请求失败';
        return Normal::returnCode(Normal::FAIL,$message,$resHttp);
    }
}